#ifndef _DWARF_FORT_STATE_MIRROR_H
#define _DWARF_FORT_STATE_MIRROR_H

#include "StandardDefines.h"
#include "AsmCall.h"

namespace Main
{
	class Logger;
};



namespace DwarfFort
{
#pragma pack(push,1)

	struct State
	{
		DWORD vf_table;
		State* nextState;
		State* prevState; 
		WORD processingState; // ?
		~State()
		{
			if (nextState) delete nextState;
		}
		State()
		{
			vf_table = 0;
			nextState = prevState = 0;
			processingState = 0;
		}
		AsmCall getVFunc(int offset) const
		{
			return AsmCall(((DWORD*)vf_table)[offset]);
		}
	};
#pragma pack(pop)


	class StateListener;

	


	class StateMirror :public Main::Loggable
	{
	public:
		StateMirror(DWORD address);
		~StateMirror();

		void updateState();

		eGameState getGameState()
		{
			if (!mStateTop) return GS_UNKNOWN;
			return mGameStateMap[mStateTop->vf_table];
		}
		const State *getTopState() const 
		{
			State* top = mStateRoot;
			while (top->nextState)
				top = top->nextState; 
			return top;
		} 
		void registerStateListener(StateListener *listener,eGameState gameState);
		void unRegisterStateListener(StateListener *listener,eGameState gameState);

	private:
		
		void fillGameStateMap();
	
		void updateListeners();
		void notifyStateRemoved(eGameState state);
		void notifyStateAdded(eGameState state);

		std::map<DWORD,eGameState> mGameStateMap;
		State *mStateRoot;
		State mStateCopy;
		State *mStateTop;

		std::vector<std::vector<StateListener *>> mStateListeners;
		std::vector<std::string> mStateNames;

		std::vector<State *> mCopiedStates;
	};














}


#endif